// bzoj1098
// 题意：有n(<=100000)个职工，他们都被公司分配一个手机，已知m(<=2000000)
//       对手机联络关系（双向）。现在公司想让员工们分到尽量多的新办公楼
//       中，但是如果两个人在不同的办公楼，那么他们直接必需存在联络关系。
//       现在让你求最多可以有多少办公楼以及每个办公楼的人数。
//
// 题解：画图观察可以知道，答案就是补图的联通分量个数，不过由于补图很大，
//       是稠密图，不可以直接建。于是我就用set维护了一个not_vis的东西（
//       也可以用list），枚举是只从这个set中枚举，访问过就删掉。访问
//       一个点补图中相邻的点可以先遍历一遍原图中相邻的点，打上标记，剩下
//       没打标记的就是补图相邻的点。
//
//       确切的复杂度不知道怎么分析，反正至少是O(n+m), 然后有原图的边数
//       限制，其他部分复杂度也不会很大。因为其他部分就是不断遍历not_vis
//       的部分，只有当补图是稀疏图是复杂度才高，但是补图是稠密图。
//
// run: $exec < input
// opt: 0
// flag: -g
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>

int const maxn = 100007;
int const maxm = 2000007;
int head[maxn], end_point[2 * maxm], next[2 * maxm];
int alloc = 2;
std::set<int> not_vis;
std::vector<int> ans;
int mark[maxn];
int n, m, tick;

void add_edge(int u, int v)
{
	end_point[alloc] = v; next[alloc] = head[u]; head[u] = alloc++;
	end_point[alloc] = u; next[alloc] = head[v]; head[v] = alloc++;
}

int bfs(int u)
{
	int ret = 1;
	std::queue<int> q;
	q.push(u);
	while (!q.empty()) {
		int now = q.front(); q.pop();
		tick++;
		for (int p = head[now]; p; p = next[p]) {
			int v = end_point[p];
			mark[v] = tick;
		}
		for (std::set<int>::iterator it = not_vis.begin(); it != not_vis.end(); ) {
			int v = *it;
			if (mark[v] != tick) {
				not_vis.erase(it++);
				ret++;
				q.push(v);
			} else
				++it;
		}
	}
	return ret;
}

int main()
{
	std::scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) not_vis.insert(i);
	for (int i = 0, x, y; i < m; i++) {
		std::scanf("%d%d", &x, &y);
		add_edge(x, y);
	}

	while (!not_vis.empty()) {
		int i = *not_vis.begin();
		if (not_vis.find(i) != not_vis.end()) {
			not_vis.erase(not_vis.begin());
			ans.push_back(bfs(i));
		}
	}
	int t = ans.size();
	std::printf("%d\n", t);
	std::sort(ans.begin(), ans.end());
	for (int i = 0; i < t; i++)
		std::printf("%d ", ans[i]);
	std::printf("\n");
}

